﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using static LightCAD.Three.Constants;

namespace LightCAD.Three
{
    public class DataTextureLoader : Loader<DataTexture>
    {
        public class TextureData
        {
            public Array data;
            public IImage image;
            public int? width;
            public int? height;
            public int? wrapS;
            public int? wrapT;
            public int? magFilter;
            public int? minFilter;
            public int? anisotropy;
            public int? encoding;
            public bool? flipY;
            public int? format;
            public int? type;
            public int? mipmapCount;
            public JsArr<Image> mipmaps;
            public bool? generateMipmaps;

            public double? exposure;
            public double? gamma;
            public string header;

        }
        public DataTextureLoader(LoadingManager manager = null)
            : base(manager)
        {

        }

        public override DataTexture load<T>(string url, Action<DataTexture, object> onLoad, onProcessDelegate onProgress, onErrorDelegate onError)
        {
            var texture = new DataTexture();
            var loader = new FileLoader(this.manager);
            loader.setResponseType("arraybuffer");
            loader.setRequestHeader(this.requestHeader);
            loader.setPath(this.path);
            loader.setWithCredentials(this.withCredentials);
            loader.load(url, (buffer) =>
            {
                var texData = (this as T).parse(buffer) as TextureData;

                if (texData == null) return;

                if (texData.image != null)
                {
                    texture.image = texData.image;
                }
                else if (texData.data != null)
                {
                    texture.image.width = (int)texData.width;
                    texture.image.height = (int)texData.height;
                    (texture.image as Image).data = texData.data;
                }

                texture.wrapS = texData.wrapS != null ? (int)texData.wrapS : ClampToEdgeWrapping;
                texture.wrapT = texData.wrapT != null ? (int)texData.wrapT : ClampToEdgeWrapping;

                texture.magFilter = texData.magFilter != null ? (int)texData.magFilter : LinearFilter;
                texture.minFilter = texData.minFilter != null ? (int)texData.minFilter : LinearFilter;

                texture.anisotropy = texData.anisotropy != null ? (int)texData.anisotropy : 1;

                if (texData.encoding != null)
                {
                    texture.encoding = (int)texData.encoding;
                }

                if (texData.flipY != null)
                {
                    texture.flipY = (bool)texData.flipY;
                }

                if (texData.format != null)
                {
                    texture.format = (int)texData.format;
                }

                if (texData.type != null)
                {
                    texture.type = (int)texData.type;
                }

                if (texData.mipmaps != null)
                {
                    texture.mipmaps = texData.mipmaps;
                    texture.minFilter = LinearMipmapLinearFilter; // presumably...
                }

                if (texData.mipmapCount == 1)
                {
                    texture.minFilter = LinearFilter;
                }

                if (texData.generateMipmaps != null)
                {
                    texture.generateMipmaps = (bool)texData.generateMipmaps;
                }

                texture.needsUpdate = true;

                if (onLoad != null) onLoad(texture, texData);

            }, onProgress, onError);
            return texture;
        }
    }
}
